<?php

namespace App\Wechat;

use App\Models\Appoint;
use App\Models\Article;
use App\Models\ArticleInfo;
use App\Models\Family;
use App\Models\FamilyEdu;
use App\Models\Hospital;
use App\Models\HospitalAppointInterval;
use App\Models\HospitalAppointType;
use App\Models\InterviewRemind;
use App\Models\Notice;
use App\Models\ScanRecord;
use App\Models\TempPushRecord;
use App\Models\User;
use App\Models\UserLogin;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Psr16Cache;

class Temp
{

    /**
     * 模板消息url
     * @var string
     */
    private static $sendUrl = "/cgi-bin/message/template/send";
    private $user_id;
    private $mini_appid;
    private $api;
    private $miniprogram;
    private $openid;
    private $template_id;
    private $url="";
    private $client_msg_id="";

    public function __construct(TempPushRecord $tempPushRecord)
    {

        $temp = \App\Models\Temp::query()->where('id', $tempPushRecord->temp_id)->first();
        if($temp) {
            $this->function_name = $temp->function_name;
            $this->template_id = $temp->template_id;
            $this->setOpenid($tempPushRecord->user_id);
            if($temp->url_type == 2 ){
                $this->miniprogram['pagepath'] = $temp->path;
                $this->miniprogram['appid'] = 'wx6835027c46b29cab';
            }else{
                $this->url = $temp->path;
            }
            $app = new Init();
            $this->api=$app->getApp()->getClient();
        }else{
            throw new \Exception($tempPushRecord->temp_id."模板不存在");
        }
    }
    public function send(Model $model)
    {
        $function = $this->function_name;;
        return $this->$function($model);
    }

    public static function combineData($data)
    {
        if(!is_array($data)){
            throw new \Exception("data 必须是数组");
        }
        $combineData = [];
        for($i=0;$i<count($data);$i++){
            $key = $i + 1;
            if(!isset($data[$i])) {
                throw new \Exception("keyword$key 不存在，请传入一维数组");
            }
            $combineData['keyword'.$key]=['value'=>$data[$i]];
        }
        return $combineData;
    }

    public function setError($msg)
    {
        $this->error = $msg;
    }
    public function setTempid($template_id)
    {
        $this->template_id = $template_id;
    }

    public function isSuccess()
    {
        return $this->error?false:true;
    }
    public function handle($data)
    {
        $options = [];

        if(isset($this->miniprogram)){
            if(!isset($this->miniprogram['appid']))
                throw new \Exception("miniprogram.appid 不能为空");
            if(!isset($this->miniprogram['pagepath']))
                throw new \Exception("miniprogram.pagepath 不能为空");
            $options['json']['miniprogram'] = $this->miniprogram;
        }

        if(!isset($this->openid))
        {
            throw new \Exception("未查询到用户 openid 不存在");
        }else{
            $options['json']['touser'] = $this->openid;
        }

        if(!isset($this->template_id)) {
            throw new \Exception("template_id 未设置");
        }else{
            $options['json']['template_id'] = $this->template_id;
        }
        $options['json']['data'] = self::combineData($data);
        $options['json']['url'] = $this->url;
        $options['json']['client_msg_id'] = $this->client_msg_id;


       // Log::info(implode(',',$options['json']));

        $response = $this->api->post(self::$sendUrl, $options);
        $wxResponse = json_decode($response->getContent(),true); // 这里会抛出异常
        if(isset($wxResponse) && $wxResponse['errcode']>0){
            throw new \Exception($wxResponse['errmsg'],$wxResponse['errcode']);
        }
    }

    public function setOpenid($user_id)
    {
        $openid = UserLogin::query()
            ->where('user_id',$user_id)
            ->value('we_openid');
        if(!$openid) {
            $openid = ScanRecord::query()
                ->where('user_id', $user_id)
                ->where('openid', '!=', '')
                ->value('openid');
        }

        $this->openid = $openid;

    }

    /**
     * 预约成功通知
     * @param Appoint $appoint
     * @return $this
     * @throws \Exception
     */
    public function AppointDone(Appoint $appoint)
    {
        $data = [];
        $data[]=HospitalAppointType::query()->where('id',$appoint->type)->value('name');
        $data[]=$appoint->family->name;
        $phone = $appoint->user->phone;
        $data[]='***' . substr($phone, -4);
        $data[]=$appoint->appoint_date;
        $appoint_time = HospitalAppointInterval::query()->where('id',$appoint->appoint_time)->first();
        $data[]=isset($appoint_time)?$appoint_time->start."-".$appoint_time->end:"";
        $this->miniprogram['pagepath'] = $this->miniprogram['pagepath'].$appoint->id;
        $this->client_msg_id = $appoint->id;
        $response = $this->handle($data);
        return $response;
    }

    /**
     * 预约失败通知
     * @param Appoint $appoint
     * @return $this
     * @throws \Exception
     */
    public function AppointCancel(Appoint $appoint)
    {
        $data[]=$appoint->family->name;
        $phone = $appoint->user->phone;
        $data[]='***' . substr($phone, -4);
        $data[]=$appoint->appoint_date;
        $data[]=HospitalAppointType::query()->where('id',$appoint->type)->value('name');
        $data[]='号源已约满请选择其他时间';

        $response = $this->handle($data);
        return $response;
    }
    /**
     * 就诊提醒通知
     * @param Appoint $appoint
     * @return $this
     * @throws \Exception
     */
    public function AppointRemind(Appoint $appoint)
    {
        $family = $appoint->family;
        $hospital = $appoint->hospital;
        $data[]=isset($family)?$family->name:"";
        //$phone = $appoint->hospital()->value('name');
        $data[]=isset($hospital)?$hospital->name:"";
        $data[]="已到院取号为准";
        $data[]=$appoint->appoint_date;
        $appoint_time = $appoint->interval();
        $teamName = isset($family) && $family->team?$family->team->name:"";
        $data[] = isset($appoint_time)?$teamName."提醒您，请于".$appoint_time->value('start')."到达社区":"";
        $data[]='';
        $this->miniprogram['pagepath'] = $this->miniprogram['pagepath'].$appoint->id;

        $response = $this->handle($data);
        return $response;
    }
    /**
     * 宣教指导通知
     * @param Appoint $appoint
     * @return $this
     * @throws \Exception
     */
    public function Edu(FamilyEdu $familyEdu)
    {
        $data[]=(string)$familyEdu->created_at;
        $data[]=$familyEdu->hospital->name;
        $data[]=$familyEdu->team->name;
        $data[]=$familyEdu->family->name;
        $data[]=$familyEdu->familyType->name."中医药儿童健康指导";
        $this->client_msg_id = $familyEdu->familyType->name."中医药儿童健康指导";

        $response = $this->handle($data);
        return $response;
    }




    /**
     * 社区推送通知
     * @param  Notice $notice
     * @return $this
     * @throws \Exception
     */
    public function ArticlePush(Notice $notice)
    {
        $hospital = Hospital::query()
            ->where('id',$notice->hospital_id)
            ->first();
        $article = ArticleInfo::query()
            ->where('article_id',$notice->article_id)
            ->first();
        $data[]=$hospital->name."签约用户";
        $data[]=date('Y年m月d日');
        $data[]=$hospital->name."提醒您:《".$article->title."》";
        $this->miniprogram['pagepath'] = $this->miniprogram['pagepath'].$notice->article_id;

        $response = $this->handle($data);
        return $response;
    }
    /**
     * 体检提醒
     * @param Appoint $appoint
     * @return $this
     * @throws \Exception
     */
    public function examinationRemind()
    {
        $this->miniprogram =  [
            'appid' => $this->mini_appid,
            'pagepath' => 'pages/index/index?id=' . $appoint->id,
        ];
        $this->setOpenid($appoint->user_id);
        $this->setTempid('b1mjgyGxK-YzQgo3IaGARjC6rkRN3qu56iDjbD6hir4');
        $response = $this->handle(['儿童保健','儿童保健']);
        return $response;
    }
    /**
     * 追访提醒提醒
     * @param InterviewRemind $interviewRemind
     * @return $this
     * @throws \Exception
     */
    public function InterviewRemind(InterviewRemind $interviewRemind)
    {
        $family = Family::query()->where('id',$interviewRemind->family_id)->first();
        if($family){
            $data[]=$family->name;
            $data[]=date('Y年m月d日');
            $data[]=InterviewRemind::$typeTxt[$interviewRemind->type];
            $this->miniprogram['pagepath'] = $this->miniprogram['pagepath'].$family->id;

            $response = $this->handle($data);
        }
        $interviewRemind->status = 1;
        $interviewRemind->save();
        return $response;
    }
}
